/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.marist.cs.os.g3.mos;

import edu.marist.cs.os.g3.processors.CPU;

/**
 *
 * @author Intern
 */
public class Memory {

    Block[] data;
    CPU cpu;
    String pageNo = new String();

    public Memory(CPU cpu) {
        this.cpu = cpu;
        data = new Block[30];
        for (int i = 0; i < data.length; i++) {
            data[i] = new Block();
        }
    }

    public boolean fillBlock(String string, int i) {
        if (!isBlockFree(i)) {
            return false;

        }
        
        data[i] = new Block(string);
        data[i].empty = false;
        return true;
    }

    public void freeBlock(int i) {
        //Since there are two separate boolenns for block and word emptiness, its best if 
        //we literally clear the block. You get an A for cleverness, simply setting it to 
        //true is pretty slick regardless!
        data[i].empty = true;
        data[i] = new Block();
    }

    public boolean isBlockFree(int i) {
        return data[i].empty;
    }

    public int firstFreeBlock() {
        for (int i = 0; i < data.length; i++) {

            if (data[i].isEmpty()) {


                return i;
            }
        }
        return -1;
    }
   
    public Word getWord(int virtualAddress, int pageTableFrame) {
        int pageNum = Integer.parseInt(Character.toString(String.format("%02d", virtualAddress).charAt(0)));
        Block pageTable = getBlock(pageTableFrame);
        Word pageWord = pageTable.getWord(pageNum);
        if (pageWord.isEmpty()) {
            cpu.PI = 3;
            return new Word();
        }
        int frameNum = Integer.parseInt(pageTable.getWord(pageNum).word);
        Word requestedWord = getBlock(frameNum).data[Integer.parseInt(Character.toString(String.format("%02d", virtualAddress).charAt(1)))];
        return requestedWord;
    }

    public void storeWord(Word word, int virtualAddress, int pageTableFrame) {
        int pageNum = Integer.parseInt(Character.toString(String.format("%02d", virtualAddress).charAt(0)));
        Block pageTable = getBlock(pageTableFrame);
        Word pageWord = pageTable.getWord(pageNum);
        if (pageWord.toString().equals(MOS.PAGE_BLANK)) {
            cpu.PI = 3;
            return;
        }

        int frameNum = Integer.parseInt(pageWord.toString());
        getBlock(frameNum).data[Integer.parseInt(Character.toString(String.format("%02d", virtualAddress).charAt(1)))] = word;
        getBlock(frameNum).empty = false;
    }

    public int translateVirtualPage(int pageNum, int pageTableFrame) {
        Block pageTable = getBlock(pageTableFrame);
        return 4;

    }

    public Block getBlock(int i) {
        return data[i];
    }

    public String toString() {
        String memory = new String();
        for (int i = 0; i < data.length; i++) {

            memory = memory + "\n" + "Frame" + i + " " + data[i].toString() + "Page Number" + " " + getPageNo(i);

        }

        return memory;
    }

    public String getPageNo(Integer x) {
        boolean found;
        for (Integer y = 0; y < 10; y++) {
            if (getBlock(cpu.PTR).getWord(y).word.equals(x.toString())) {
                pageNo = y.toString();
                break;
            } else {
                pageNo = "    ";
            }
        }
        return pageNo;
    }
}